<?php
/**
 * @copyright   2008-2021 简好网络 <http://www.phpshe.com>
 * @creatdate   2010-1001 koyshe <koyshe@gmail.com>
 */
class upload {
	public $file;
	public $host;//url全路径
	public $path;//path全路径
	public $filehost;//url相对路径+文件
	public $filepath;//path相对路径+文件
	public $filehost_full;//url全路径+文件
	public $filepath_full;//path全路径+文件
	//上传的文件名(原文件名)
	public $filename_old = '';
	//上传的文件名
	public $filename = '';
	//上传的文件后缀
	public $filetail = '';
	//允许上传的文件类型
	public $_filetype = array('jpg','jpeg','gif','png','psd','wps','doc','xls','xlsx','csv','ppt','pdf','zip','rar','tar','txt','text','mp4', 'flv', 'mp3', 'wav');
	//文件上传大小控制(默认是10000kb)
	public $_filesize = 100000000;
	//报错信息
	public $error = '';
	function __construct($file, $path_save = null, $ext_arr = array())
	{
		global $pe;
		$this->file = $file;
		//配置存储路径（支持两种模式1：默认上传到默认附件目录里2：上传到自定义目录里）
		!$path_save && $path_save = 'data/attachment/'.date('Y-m').'/';

		$this->host = "{$pe['host']}{$path_save}";
		$this->path = "{$pe['path']}{$path_save}";
		
		$this->filetail = $this->filetail();
		$this->filename_old = $this->file['name'];
		$this->filename = $this->filename($ext_arr['filename']);

		$this->filehost = $this->filepath = "{$path_save}{$this->filename}";
		$this->filehost_full = "{$this->host}{$this->filename}";
		$this->filepath_full = "{$this->path}{$this->filename}";

		$ext_arr['filetype'] && $this->_filetype = $ext_arr['filetype'];
		$ext_arr['filesize'] && $this->_filesize = $ext_arr['filesize'];
		
		//检测文件合法性
		$this->file_check();
		if ($this->error) return;
		//上传移动临时文件
		$this->file_move();
		if ($this->error) return;
		//同步到oss
		if ($ext_arr['local'] != 1) $this->syn_oss();
		if ($this->error) return;
	}
	//检测文件的合法性
	function file_check()
	{
		if (!$this->filename_old) {
			$this->error = '请选择文件';
			return;
		}
		if (@is_dir($this->path) === false) {
			mkdir($this->path, 0777, true);
		}
		if ($this->file['size'] > $this->_filesize) {
			$this->error = '上传文件大小超过限制';
			return;
		}
		if (!in_array(trim($this->filetail, '.'), $this->_filetype)) {
			$this->error = '上传文件类型不被允许';
			return;
		}
	}
	//上传文件重命名
	function filename($filename)
	{
		if ($filename) {
			return $filename . $this->filetail;
		}
		else {
			usleep(500000);
			$rand_arr = array_merge(range('a','z'),range('A','Z'),range(0,1));
			$name_tmp1 = $rand_arr[array_rand($rand_arr, 1)].$rand_arr[array_rand($rand_arr, 1)].$rand_arr[array_rand($rand_arr, 1)];
			$name_tmp2 = microtime().rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9);
			$name_tmp3 = base64_encode($this->filename_old).uniqid(mt_rand(), true);
			$name_tmp = md5($name_tmp1.$name_tmp2.$name_tmp3);
			return date("YmdHis") . '_' .$name_tmp . $this->filetail;
		}
	}
	//获取文件扩展名
	function filetail()
	{
		//$filearr = explode('.', $this->filename_old);
		//return strtolower($filearr[count($filearr) - 1]);
		return strtolower(strrchr($this->file['name'], '.'));
	}
	//上传文件移动到存储目录
	function file_move()
	{
		if (move_uploaded_file($this->file['tmp_name'], $this->filepath_full) === false) {
			$this->error = '上传失败';
			return;
		}
	}
	//同步到第三方oss平台
	function syn_oss() {
		global $cache_setting;
		if ($cache_setting['upload_server'] == 'aliyun') {
			$config['accessid'] = $cache_setting['upload_aliyun_accesskey_id'];
			$config['accesskey'] = $cache_setting['upload_aliyun_accesskey_secret'];
			$config['url'] = trim($cache_setting['upload_aliyun_domain'], '/').'/';
			//设置policy参数（过期时间+文件大小+文件名限制）
			$policy_param['expiration'] = $this->gmt_iso8601(time() + 1800);
			//最大文件大小.用户可以自己设置
			$policy_param['conditions'][] = array(0=>'content-length-range', 1=>0, 2=>1048576*500);
			// 表示用户上传的数据，必须是以$dir开始，不然上传会失败，这一步不是必须项，只是为了安全起见，防止用户通过policy上传到别人的目录。
			//$policy['conditions'][] = array(0=>'starts-with', 1=>'$key', 2=>$dir);
			$policy = base64_encode(json_encode($policy_param));
			$sign = base64_encode(hash_hmac('sha1', $policy, $config['accesskey'], true));
			$post['OSSAccessKeyId'] = $config['accessid'];
			$post['x-oss-content-type'] = $this->file['type'];
			$post['policy'] = $policy;
			$post['Signature'] = $sign;
			$post['key'] = $this->filehost;
			$post['success_action_status'] = '200';
			$post['ETag'] = '';
			$post['name'] = $this->filename_old;
			$post['file'] = "@{$this->filepath_full}";
			$post['filetype'] = $this->filetail;
			if (pe_curl_post($config['url'], $post)) {
				$this->error = '同步OSS失败';
				return;
			}
			unlink($this->filepath_full);
			$this->filehost_full = $this->filehost = $config['url'].$this->filehost;
		}	
	}
	//时间格式转换
	function gmt_iso8601($time) {
	    $dtStr = date("c", $time);
	    $mydatetime = new DateTime($dtStr);
	    $expiration = $mydatetime->format(DateTime::ISO8601);
	    $pos = strpos($expiration, '+');
	    $expiration = substr($expiration, 0, $pos);
	    return $expiration."Z";	
	}
}
?>